package dao

import (
	"context"
	"github.com/go-xorm/xorm"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gomodule/redigo/redis"
	"twokick/conf"
	log "github.com/sirupsen/logrus"
	"fmt"
	"time"
)

type Interface interface {
	Close()
	Ping(ctx context.Context)error
}

type Dao struct {
	db 	*xorm.Engine
	redis  map[string]*redis.Pool
}
func checkErr(e error) {
	if e != nil {
		panic(e)
	}
}
func New(conf *conf.HttpConf) *Dao {
	var (
		dao = new(Dao)
		mysqlConf 	 = conf.Mysql
		dc 	*xorm.Engine
		e 		error
	)

	dc, e = xorm.NewEngine("mysql", mysqlConf.Addr)
	checkErr(e)
	e = dc.Ping()
	checkErr(e)
	dc.ShowSQL(mysqlConf.ShowSQL)
	dc.SetMaxIdleConns(mysqlConf.MaxIdleConns)
	dc.SetMaxOpenConns(mysqlConf.MaxOpenConns)

	fmt.Println(mysqlConf.MaxConnMaxLifeTime)

	dc.SetConnMaxLifetime(time.Duration(mysqlConf.MaxConnMaxLifeTime) * time.Second)

	dao.db = dc
	dao.redis = make(map[string]*redis.Pool)
	for k, v := range conf.RedisMap {
		fmt.Println("redis:",k," addr:",v.Addr)
		dao.redis[k] = &redis.Pool{
			// 从配置文件获取maxIdle以及maxActive，取不到则用后面的默认值
			MaxIdle:			v.MaxIdle,				// 空闲时最大链接数量
			MaxActive: 		v.MaxActive,				// 最大在使用数量
			IdleTimeout: 	time.Duration(v.IdleTimeout) * time.Second,
			Wait:					v.Wait,
			Dial: func() (redis.Conn, error) {
				// 可以使用 SELECT 选择数据库
				conn, err := redis.Dial("tcp", v.Addr)
				return conn,err
			},
		}
	}
	return dao
}
func (d *Dao) Close() {
	fmt.Println("dao close!")
	d.db.Close()
	for _,v := range d.redis {
		v.Close()
	}
}
func (d *Dao) Ping(ctx context.Context) (err error) {
	if err = d.pingRedis(ctx); err != nil {
		return err
	}
	return d.db.Ping()
}
func(d *Dao) pingRedis(ctx context.Context)(err error){
	for k , v := range d.redis {
		conn := v.Get()
		if _, err = conn.Do("SET", "ping", "pong"); err != nil {
			log.Error(k," redis ping error:",err)
		}
		conn.Close()
	}
	return
}